package free.mrchen23.util.pool;

import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import java.util.NoSuchElementException;
import java.util.concurrent.TimeUnit;

public class ObjectPoolCenter<T> {

    private final ObjectPool<T> objectPool;

    protected ObjectPoolCenter(ObjectPool<T> objectPool) {
        this.objectPool = objectPool;
    }

    public T borrowObject() throws Exception, NoSuchElementException,
            IllegalStateException {
        return objectPool.borrowObject();
    }

    public void returnObject( T obj ) {
        if ( null == obj ) {
            return;
        }
        try {
            objectPool.returnObject(obj);
        } catch (Exception e) {
            //
        }
    }

    public void clear() {
        try {
            objectPool.clear();
        } catch (Exception e) {
            //
        }
    }

    public static <T> Builder<T> builder() {
        return new Builder<T>();
    }

    public static class Builder<T> {

        private int min;

        private int max;

        private long waitTime;

        private TimeUnit waitTimeUnit;

        private PooledObjectFactory<T> objectFactory;

        public Builder<T> min( int min ) {
            this.min = min;
            return this;
        }

        public Builder<T> max( int max ) {
            this.max = max;
            return this;
        }

        public Builder<T> waitTime( long waitTime , TimeUnit timeUnit ) {
            this.waitTime = waitTime;
            this.waitTimeUnit = timeUnit;
            return this;
        }

        public Builder<T> factory( PooledObjectFactory<T> factory ) {
            this.objectFactory = factory;
            return this;
        }


        public ObjectPoolCenter<T> build() {
            GenericObjectPoolConfig<T> config = new GenericObjectPoolConfig<T>();
            config.setMaxIdle( max );
            config.setMaxTotal( max );
            config.setMinIdle( min );
            config.setMaxWaitMillis( waitTimeUnit.toMillis(waitTime) );
            GenericObjectPool<T> objectPool = new GenericObjectPool<T>(objectFactory,config);
            return new ObjectPoolCenter<T>( objectPool ){};
        }


    }

}
